home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 14323 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  3.4 KB

  1. Path: mail2news.demon.co.uk!genesis.demon.co.uk
  2. From: Lawrence Kirby <fred@genesis.demon.co.uk>
  3. Newsgroups: comp.lang.c
  4. Subject: Re: A little shift to the left and a little shift to the right.
  5. Date: Sat, 13 Apr 96 13:42:01 GMT
  6. Organization: none
  7. Message-ID: <829402921snz@genesis.demon.co.uk>
  8. References: <4knegm$40d@crl.crl.com>
  9. Reply-To: fred@genesis.demon.co.uk
  10. X-NNTP-Posting-Host: genesis.demon.co.uk
  11. X-Newsreader: Demon Internet Simple News v1.27
  12. X-Mail2News-Path: genesis.demon.co.uk
  13.  
  14. In article <4knegm$40d@crl.crl.com> smuegge@crl.com "Shad Muegge" writes:
  15.  
  16. >Our trusty PL/M-to-C translator generated the C operators << and >>
  17. >whenever it encountered the PL/M operators SHL and SHR. 
  18.  
  19. I wouldn't call it so 'trusty'!
  20.  
  21. >In one case the original coder had used these bit shifting operators
  22. >to clear out the top nibble of a byte using the following code. 
  23. >(Actually this is the C code the translator generated less the
  24. >proprietary variable names. :))
  25. >
  26. >   x = ( ( y << 4 ) >> 4 );
  27. >
  28. >   (The name of the coder will remain a secret, and yes I know a
  29. >    simple "& 0x0f" would be a more obvious solution. but the same
  30. >    problem is exhibited for any left-shift followed by a right-shift)
  31.  
  32. & 0x0f assumes 8 bit bytes, but maybe PL/M does guarantee that (although
  33. C doesn't).
  34.  
  35. >Both the variables x and y are bytes ( unsigned chars ). 
  36. >
  37. >The results of this code is the the value of y is assigned to
  38. >x without any modification.  The same results as simple assignment
  39. >(x = y).  It turns out that every C compiler I've tried ( Intel-C,
  40. >Microsoft VC++, and gcc) exhibits this same behaviour. 
  41.  
  42. That is the correct behaviour on those systems. The >> and << operators
  43. define that 'the integral promotions' are performed on their operands.
  44. Therefore an unsigned char operand is first promoted to int (or just
  45. possibly unsigned int) and the result has that same type. Your PL/M to C
  46. converter is in error here (assuming PL/M doesn't do any implicit
  47. widening).
  48.  
  49. >Looking at the assembly code generated by all three compilers the
  50. >reason the shifts have no effect is because they do them with 32 
  51. >bit registers.  So, when the bits are shifted to the left by 4 they
  52. >aren't "lost" as one might expect.  Then the right shift just 
  53. >returns all the bits to original position. 
  54.  
  55. That is what should happen where int is at least 4 bits wider than char
  56. (or at least 5 bits if you don't want to hit sign bit issues). On systems
  57. with 8 bit chars that is guaranteed (since ints must be at least 16 bits).
  58.  
  59. >By using a typecast two of the compilers (Intel-C and gcc) will 
  60. >do what the original coder intended, mask off the the top nibble of
  61. >a byte. Microsoft's compiler just ignored the typecast and 
  62. >generated the same code as it did without the typecast.
  63. >
  64. >  x = ( ( unsigned char ) ( y << 4 ) >> 4 );
  65.  
  66. That is correct code since the intermediate result is forced to an
  67. unsigned char and hence the top 4 bits from the original value are cleared.
  68. If your Microsoft compiler doesn't do this correctly then it is broken.
  69.  
  70. Coincidentally I have a SCO system here which has gcc, cc (Microsoft) and
  71. icc (Intel) compilers on it. All worked correctly with that code, in fact
  72. it was only the Intel optimising compiler that didn't spot the optimisation
  73. to y & 0x0f.
  74.  
  75. -- 
  76. -----------------------------------------
  77. Lawrence Kirby | fred@genesis.demon.co.uk
  78. Wilts, England | 70734.126@compuserve.com
  79. -----------------------------------------
  80.